home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 4
/
Amiga Tools 4.iso
/
grafix
/
raytracing
/
raylab
/
source
/
texture.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-14
|
4KB
|
189 lines
/*
name: texture.c
Textures
--------
Texture-calculation and texture-handling.
*/
#include "defs.h"
void CreateDefTexture(TEXTURE *t)
{
t->CMap.Colors[0].r=1.0; t->CMap.Colors[0].g=0.3; t->CMap.Colors[0].b=0.0;
t->CMap.Colors[1].r=0.0; t->CMap.Colors[1].g=0.0; t->CMap.Colors[1].b=0.0;
t->CMap.LastBound=1;
t->Pattern=PATTERN_NONE;
t->Reflect.r=t->Reflect.g=t->Reflect.b=0.0;
t->Filter.r=t->Filter.g=t->Filter.b=0.0;
t->Ior=0.0;
t->Ambient=0.2;
t->Diffuse=0.8;
t->Phong=0.3; t->PhongSize=10.0;
ClearTransform(&t->Transform);
}
void CopyTexture(TEXTURE *t2, TEXTURE *t1)
{
long i,lbound;
lbound=t1->CMap.LastBound;
for(i=0;i<=lbound;i++) {
t2->CMap.Bounds[i]=t1->CMap.Bounds[i];
t2->CMap.Colors[i].r=t1->CMap.Colors[i].r;
t2->CMap.Colors[i].g=t1->CMap.Colors[i].g;
t2->CMap.Colors[i].b=t1->CMap.Colors[i].b;
}
t2->CMap.LastBound=lbound;
t2->Pattern=t1->Pattern;
t2->Reflect.r=t1->Reflect.r;
t2->Reflect.g=t1->Reflect.g;
t2->Reflect.b=t1->Reflect.b;
t2->Filter.r=t1->Filter.r;
t2->Filter.g=t1->Filter.g;
t2->Filter.b=t1->Filter.b;
t2->Ior=t1->Ior;
t2->Ambient=t1->Ambient;
t2->Diffuse=t1->Diffuse;
t2->Phong=t1->Phong;
t2->PhongSize=t1->PhongSize;
CopyTransform(&t2->Transform,&t1->Transform);
}
void CopyColor(COLOR *c2, COLOR *c1)
{
c2->r=c1->r; c2->g=c1->g; c2->b=c1->b;
}
/**************************************************************
*
* Here are some useful (more or less) texture-patterns.
*
**************************************************************/
void GetSurfaceColor(COLOR *Color, TEXTURE *t, POINT *ip)
{
double MapValue;
int indx,foundindx,i;
COLORMAP *cm;
VECTOR tempv;
POINT temppoint;
CopyPoint(&temppoint,ip);
if((t->Transform.NumTransforms>0)&&(t->Pattern!=PATTERN_NONE)) {
for(i=t->Transform.NumTransforms-1L;i>=0L;i--) {
switch(t->Transform.Entry[i].Type) {
case TRANSFORM_SCALE:
temppoint.x=temppoint.x/t->Transform.Entry[i].Values.x;
temppoint.y=temppoint.y/t->Transform.Entry[i].Values.y;
temppoint.z=temppoint.z/t->Transform.Entry[i].Values.z;
break;
case TRANSFORM_MOVE:
temppoint.x=temppoint.x-t->Transform.Entry[i].Values.x;
temppoint.y=temppoint.y-t->Transform.Entry[i].Values.y;
temppoint.z=temppoint.z-t->Transform.Entry[i].Values.z;
break;
case TRANSFORM_ROTATE:
NegVector(&tempv,&t->Transform.Entry[i].Values);
RotatePoint(&temppoint,&tempv);
break;
case TRANSFORM_NONE:
default:
break;
}
}
}
switch(t->Pattern) {
case PATTERN_CHECKER:
MapValue=PatternChecker(&temppoint);
break;
case PATTERN_CIRCLES:
MapValue=PatternCircles(&temppoint);
break;
case PATTERN_RINGS:
MapValue=PatternRings(&temppoint);
break;
case PATTERN_SPOTS:
MapValue=PatternSpots(&temppoint);
break;
case PATTERN_GRADIENT:
MapValue=PatternGradient(&temppoint);
break;
case PATTERN_NONE:
default:
MapValue=0.0;
break;
}
cm=&t->CMap;
foundindx=-1;
if(MapValue>EPSILON) {
indx=0;
while((indx<cm->LastBound)&&(foundindx!=0)) {
if((MapValue>=cm->Bounds[indx])&&(MapValue<=cm->Bounds[indx+1]))
foundindx=0;
else indx++;
}
}
if(foundindx==0) {
Color->r=(cm->Colors[indx].r*(cm->Bounds[indx+1]-MapValue)+cm->Colors[indx+1].r*(MapValue-cm->Bounds[indx]))/(cm->Bounds[indx+1]-cm->Bounds[indx]);
Color->g=(cm->Colors[indx].g*(cm->Bounds[indx+1]-MapValue)+cm->Colors[indx+1].g*(MapValue-cm->Bounds[indx]))/(cm->Bounds[indx+1]-cm->Bounds[indx]);
Color->b=(cm->Colors[indx].b*(cm->Bounds[indx+1]-MapValue)+cm->Colors[indx+1].b*(MapValue-cm->Bounds[indx]))/(cm->Bounds[indx+1]-cm->Bounds[indx]);
}
else {
Color->r=cm->Colors[0].r;
Color->g=cm->Colors[0].g;
Color->b=cm->Colors[0].b;
}
}
double PatternChecker(POINT *ip)
{
return( (double)(((long)floor(ip->x+EPSILON)+(long)floor(ip->y+EPSILON)+(long)floor(ip->z+EPSILON))&1L) );
}
double PatternCircles(POINT *ip)
{
return(fmod(sqrt(ip->x*ip->x+ip->y*ip->y+ip->z*ip->z),1.0));
}
double PatternRings(POINT *ip)
{
return(fmod(sqrt(ip->x*ip->x+ip->y*ip->y),1.0));
}
double PatternSpots(POINT *ip)
{
double d;
POINT dgrid;
dgrid.x=ip->x-floor(ip->x+0.5);
dgrid.y=ip->y-floor(ip->y+0.5);
dgrid.z=ip->z-floor(ip->z+0.5);
d=2.0*sqrt(dgrid.x*dgrid.x+dgrid.y*dgrid.y+dgrid.z*dgrid.z);
if(d>1.0) d=1.0;
return(d);
}
double PatternGradient(POINT *ip)
{
if(ip->z>0) return(fmod(fabs(ip->z),1.0));
else return(fmod(1.0-fabs(ip->z),1.0));
}